# 购物车合并逻辑,不作为视图,作为工具使用
import base64
import pickle

from django_redis import get_redis_connection


def merge_cart_cookie_to_redis(request, user, response):
    """
    登陆时合并购物车,将cookis中的数据合并到redis 中
    登陆时候cookies和redis中商品数据相同时,以cookie为准
    :param request: 传入的请求对象
    :param user: 传入的用户对象
    :param reponse: 传入的返回对象
    :return:
    """
    # 获取cookies 中的数据
    cookie_cart = request.COOKIES.get('cart')
    # 没有数据,不用合并直接返回
    if not cookie_cart:
        return response

    # 有,解析
    cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))
    # 获取redis 中的商品数量数据
    # redis_cart = {
    #     商品的sku_id  bytes字节类型: 数量  bytes字节类型
    #     商品的sku_id  bytes字节类型: 数量  bytes字节类型
    #    ...
    # }
    redis_conn = get_redis_connection('cart')
    redis_cart = redis_conn.hgetall('cart_%s' % user.id)

    # 用来存储redis中最终保存商品数量的信息
    cart = {}
    for sku_id, count in redis_cart.items():
        cart[int(sku_id)] = int(count)

    # 用来存储redis最终操作时,哪些sku_id是需要勾选新增的
    redis_cart_selected_add = []

    # 用来存储redis最终操作时,哪些sku_id是要取消勾选的
    redis_cart_selected_remove = []

    # 遍历cookie购物车,关于商品数量的东西,多则添加,有则覆盖
    # cookie_cart_dict = {
    #     sku_id_1: {
    #         'count': 10
    #         'selected': True
    #     },
    #     sku_id_2: {
    #         'count': 10
    #         'selected': False
    #     },
    # }
    for sku_id, count_dict in cookie_cart_dict.items():
        cart[sku_id] = count_dict['count']

        if count_dict['selected']:
            # 指明勾选的
            redis_cart_selected_add.append(sku_id)
        else:
            # 指明不勾选
            redis_cart_selected_remove.append(sku_id)

    # cookie和redis的购物车都没有数据的话,不处理
    if cart:
        # 执行redis操作
        pl = redis_conn.pipeline()

        # 设置redis的hash数据
        pl.hmset('cart_%s' % user.id, cart)

        # 设置set类型
        if redis_cart_selected_add:
            # 有就做,没有就不做
            pl.sadd('cart_selected_%s' % user.id, *redis_cart_selected_add)

        if redis_cart_selected_remove:
            pl.srem('cart_selected_%s' % user.id, *redis_cart_selected_remove)

        pl.execute()

    # 合并了就删除cookie
    response.delete_cookie('cart')
    return response